﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Threading.Tasks;
using static SqlSugarAndEntity.DataModel;

namespace IBaseRepository
{
    public interface IBaseRepository<T> where T:class,new()
    {
        #region 同步方法
        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        bool Insert(T entity);
        /// <summary>
        /// 插入数据,忽略指定列
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="IgnoreColumns">形如t=>new {t.Createdate}</param>
        /// <returns></returns>
        bool InsertIgnoreColumns(T entity, Expression<Func<T, object>> IgnoreColumns);
        /// <summary>
        /// 插入数据,只插入指定列
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="AppiontColumns">形如t=>new {t.Createdate}</param>
        /// <returns></returns>
        bool InsertAppiontColumns(T entity, Expression<Func<T, object>> AppiontColumns);
        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool Update(T entity);
        /// <summary>
        /// 通过t=>new {t.ID}的形式指定where条件更新
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="WhereSelect">形似t=>new {t.ID}</param>
        /// <returns></returns>
        bool Update(T entity, Expression<Func<T, object>> WhereSelect);
        /// <summary>
        /// 根据表达式更新实体
        /// </summary>
        /// <param name="SetColumns">需要更新的字段 形似 t=>new T(){UpdateColumn=1}</param>
        /// <param name="WhereCondition">where表达式 t=>t.id==1</param>
        /// <returns></returns>
        bool Update(Expression<Func<T,T>> SetColumns, Expression<Func<T, bool>> WhereCondition=null);
        /// <summary>
        /// 通过t=>t.new T(){Field="1"}的形式指定where条件和忽略更新的字段
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="WhereSelect">形似t=>new {t.ID}</param>
        /// <param name="IgnoreExpress">形似t=>new {t.IgnoreColumn}</param>
        /// <returns></returns>
        bool UpdateIgnoreColumns(T entity, Expression<Func<T, object>> WhereSelect, Expression<Func<T, object>> IgnoreExpress);
        /// <summary>
        /// 通过t=>t.new T(){Field="1"}的形式指定where条件和只更新的字段
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="WhereSelect">形似t=>new {t.ID}</param>
        /// <param name="UpdateExpress">形似t=>new {t.UpdateColumn}</param>
        /// <returns></returns>
        bool UpdateAppiontColumns(T entity, Expression<Func<T, object>> WhereSelect, Expression<Func<T, object>> UpdateExpress);
        /// <summary>
        /// 有ID就更新 没ID就保存
        /// </summary>
        /// <param name="list"></param>
        /// <param name="SaveExpress"></param>
        void SaveOrUpdate(List<T> list, Expression<Func<T, object>> SaveExpress=null);
        /// <summary>
        /// 有ID就更新 没ID就保存
        /// </summary>
        /// <param name="list">实体list</param>
        /// <param name="SaveExpress">主键表达式 例如t=>new {t.id} 实体设置主键可以为null</param>
        /// <param name="func">执行分组后的操作</param>
        void SaveOrUpdate(List<T> list, Expression<Func<T, object>> SaveExpress = null,Action<StorageableResult<T>> func = null);
        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool Delete(T entity);
        /// <summary>
        /// 根据表达式删除数据
        /// </summary>
        /// <param name="WhereExp"></param>
        /// <returns></returns>
        bool Delete(Expression<Func<T, bool>> WhereExp);
        /// <summary>
        /// 根据表达式获取全部的数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returns></returns>
        List<T> GetInfo(Expression<Func<T, bool>> predicate);
        /// <summary>
        /// 根据查询表达式和排序表达式获取正序排列的全部数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <returns></returns>
        List<T> GetOrderbyAscInfo(Expression<Func<T, bool>> predicate,Expression<Func<T,object>>orderBy);
        /// <summary>
        /// 根据查询表达式和排序表达式获取倒序排列的全部数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <returns></returns>
        List<T> GetOrderbyDescInfo(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy);
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">数据总数</param>
        /// <returns></returns>
        PageListModel<T> GetInfoByPage(Expression<Func<T, bool>> predicate,int page,int limit);
        /// <summary>
        /// 获取正序排序后分页数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        PageListModel<T> GetOrderbyAscInfoByPage(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy,int page, int limit);
        /// <summary>
        /// 获取倒序排序后分页数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        PageListModel<T> GetOrderbyDescInfoByPage(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy, int page, int limit);
        /// <summary>
        /// 根据sql获取datatable
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns></returns>
        DataTable FromSql(string sql);
        /// <summary>
        /// 执行sql
        /// </summary>
        /// <param name="sql">执行的sql语句</param>
        int ExecuteSqlCommand(string sql);
        /// <summary>
        /// 批量插入list
        /// </summary>
        /// <param name="list">实体list</param>
        void Insert(List<T> list);
        /// <summary>
        /// 批量删除list
        /// </summary>
        /// <param name="list">实体list</param>
        void Delete(List<T> list);
        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="list"></param>
        bool Update(List<T> list);
        /// <summary>
        /// 批量更新 指定更新条件
        /// </summary>
        /// <param name="list">list</param>
        /// <param name="WhereExp">形似t=>new {t.ID}</param>
        /// <returns></returns>
        bool Update(List<T> list, Expression<Func<T, object>> WhereExp);
        /// <summary>
        /// 开启事务执行接下来的所有操作
        /// </summary>
        /// <param name="action">执行的方法</param>
        void BeginTran(Action<ISqlSugarClient> action);
        /// <summary>
        /// 根据查询表达式获取数据datable
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returns></returns>
        DataTable GetInfoToDataTable(Expression<Func<T, bool>> predicate);
        /// <summary>
        /// 根据查询表达式获取分页后的数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">总页数</param>
        /// <returns></returns>
        PageDataTable GetInfoToDataTableByPage(Expression<Func<T, bool>> predicate, int page, int limit);
        #endregion
        #region 异步方法
        /// <summary>
        /// 异步插入
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<bool> InsertSync(T entity);
        /// <summary>
        /// 异步插入数据,忽略指定列
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="IgnoreColumns">形如t=>new {t.Createdate}</param>
        /// <returns></returns>
        Task<bool> InsertIgnoreColumnsSync(T entity, Expression<Func<T, object>> IgnoreColumns);
        /// <summary>
        /// 异步插入数据,只插入指定列
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="AppiontColumns">形如t=>new {t.Createdate}</param>
        /// <returns></returns>
        Task<bool> InsertAppiontColumnsSync(T entity, Expression<Func<T, object>> AppiontColumns);
        /// <summary>
        /// 异步更新实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> UpdateSync(T entity);
        /// <summary>
        /// 异步通过t=>new {t.ID}的形式指定where条件更新
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="WhereSelect">形似t=>new {t.ID}</param>
        /// <returns></returns>
        Task<bool> UpdateSync(T entity, Expression<Func<T, object>> WhereSelect);
        /// <summary>
        /// 异步根据表达式更新实体
        /// </summary>
        /// <param name="SetColumns">需要更新的字段 形似 t=>new T(){UpdateColumn=1}</param>
        /// <param name="WhereSelect">where表达式 形似t=>new {t.ID}</param>
        /// <returns></returns>
        Task<bool> UpdateSync(Expression<Func<T, T>> SetColumns, Expression<Func<T, bool>> WhereCondition);
        /// <summary>
        /// 异步通过t=>t.new T(){Field="1"}的形式指定where条件和忽略更新的字段
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="WhereSelect">形似t=>new {t.ID}</param>
        /// <param name="IgnoreExpress">形似t=>new {t.IgnoreColumn}</param>
        /// <returns></returns>
        Task<bool> UpdateIgnoreColumnsSync(T entity, Expression<Func<T, object>> WhereSelect, Expression<Func<T, object>> IgnoreExpress);
        /// <summary>
        /// 异步通过t=>t.new T(){Field="1"}的形式指定where条件和只更新的字段
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="WhereSelect">形似t=>new {t.ID}</param>
        /// <param name="UpdateExpress">形似t=>new {t.UpdateColumn}</param>
        /// <returns></returns>
        Task<bool> UpdateAppiontColumnsSync(T entity, Expression<Func<T, object>> WhereSelect, Expression<Func<T, object>> UpdateExpress);
        /// <summary>
        /// 异步删除实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> DeleteSync(T entity);
        /// <summary>
        /// 异步根据表达式删除数据
        /// </summary>
        /// <param name="WhereExp"></param>
        /// <returns></returns>
        Task<bool> DeleteSync(Expression<Func<T, bool>> WhereExp);
        /// <summary>
        /// 异步根据表达式获取全部的数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returns></returns>
        Task<List<T>> GetInfoSync(Expression<Func<T, bool>> predicate);
        /// <summary>
        /// 异步根据查询表达式和排序表达式获取正序排列的全部数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <returns></returns>
        Task<List<T>> GetOrderbyAscInfoSync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy);
        /// <summary>
        /// 异步根据查询表达式和排序表达式获取倒序排列的全部数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <returns></returns>
        Task<List<T>> GetOrderbyDescInfoSync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy);
        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">数据总数</param>
        /// <returns></returns>
        Task<PageListModel<T>> GetInfoByPageSync(Expression<Func<T, bool>> predicate, int page, int limit);
        /// <summary>
        /// 异步获取正序排序后分页数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        Task<PageListModel<T>> GetOrderbyAscInfoByPageSync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy, int page, int limit);
        /// <summary>
        /// 异步获取倒序排序后分页数据
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        Task<PageListModel<T>> GetOrderbyDescInfoByPageSync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBy, int page, int limit);
        /// <summary>
        /// 异步根据sql获取datatable
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returns></returns>
        Task<DataTable> FromSqlSync(string sql);
        /// <summary>
        /// 异步异步批量插入list
        /// </summary>
        /// <param name="list">实体list</param>
        Task InsertSync(List<T> list);
        /// <summary>
        /// 异步异步执行sql
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        Task<int> ExecuteSqlCommandSync(string sql);
        /// <summary>
        /// 异步批量删除list
        /// </summary>
        /// <param name="list">实体list</param>
        Task DeleteSync(List<T> list);
        /// <summary>
        /// 异步批量更新
        /// </summary>
        /// <param name="list"></param>
        Task UpdateSync(List<T> list);
        /// <summary>
        /// 异步批量更新 指定更新条件
        /// </summary>
        /// <param name="list">list</param>
        /// <param name="WhereExp">形似t=>new {t.ID}</param>
        /// <returns></returns>
        Task UpdateSync(List<T> list, Expression<Func<T, object>> WhereExp);
        /// <summary>
        /// 异步根据查询表达式获取数据datable
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returns></returns>
        Task<DataTable> GetInfoToDataTableSync(Expression<Func<T, bool>> predicate);
        #endregion
    }
}
